package com.fone.player.storage;

import java.io.File;
import java.util.ArrayList;
import java.util.Locale;

import android.content.Context;
import android.os.Message;

import com.fone.player.R;
import com.fone.player.entity.MediaFile;
import com.fone.player.entity.MediaFolder;
import com.fone.player.util.L;
import com.fone.player.util.SystemUtil;

import de.greenrobot.event.EventBus;

/**
 * 
 * 完整扫描
 * 
 * @author wangyang
 * @since 2014年4月23日
 */
public class FileFullScanRunnable implements Runnable {
	private static final String TAG = FileFullScanRunnable.class
			.getSimpleName();
	// 文件集合
	private ArrayList<MediaFile> mMediaFileList = new ArrayList<MediaFile>();
	// 文件夹和文件集合
	private ArrayList<MediaFolder> mMediaFolderList = new ArrayList<MediaFolder>();
	private Context mContext = null;
	private boolean mIsStop = false;
	private long mTotalFileNum = 0;
	private long mMediaFileNum = 0;

	FileFullScanRunnable(Context context) {
		mContext = context;
	}

	@Override
	public void run() {
		synchronized (TAG) {
			try {

				// 扫描开始
				Message message = new Message();
				message.what = StorageModule.MSG_ACTION_SCANNER_STARTED;
				EventBus.getDefault().post(message);

				// 获取挂载的路径
				ArrayList<String> rootDrive = SystemUtil.getAllStoragePath();

				if (rootDrive != null) {
					L.v(TAG, "rootDrive.toArray() frist:" + rootDrive);

					// append '/' at the tail
					for (int i = 0; i < rootDrive.size(); i++) {
						String str = rootDrive.get(i);
						if (!str.endsWith("/"))
							rootDrive.set(i, str + "/");
					}

					// check whether one path is a subpath of another
					for (int i = 0; i < rootDrive.size() - 1; i++) {
						String str1 = rootDrive.get(i);
						for (int k = i + 1; k < rootDrive.size(); k++) {
							String str2 = rootDrive.get(k);

							// 检测目录是否相同
							if (str1.equals(str2)) {
								rootDrive.remove(k);
								k--; // retry the position
								continue;
							}

							// 检测目录是否互相包含
							if (str1.startsWith(str2)) {
								// [i] is subpath of [k], remove [i]
								rootDrive.remove(i);
								i--; // retry the postion
								break; // break from the inner loop
							} else if (str2.startsWith(str1)) {
								// [k] is subpath of [i], remove [k]
								rootDrive.remove(k);
								k--; // retry the position
								continue;
							}
						}
					}

					// scan these folders
					for (int i = 0; i < rootDrive.size(); i++) {
						// fix bug for MOTO XT910
						String homeStr = rootDrive.get(i);
						String[] homeArry = homeStr.split(":");
						File home = new File(homeArry[0]);
						if (home != null) {
							L.v(TAG, "home:" + home);
							searchMdeiaFile(home);
						}
					}
				}

				if (!mIsStop) {

					// 过滤空文件夹
					for (MediaFolder mediaFolder : mMediaFolderList) {
						if (mediaFolder.getMediaFolderTotalNum() == 0) {
							mMediaFolderList.remove(mediaFolder);
						}
					}
					// 入库
					FileDataBaseAdapter.getInstance().addFolderList(
							mMediaFolderList, mMediaFileList);
					// 扫描完成
					message.what = StorageModule.MSG_ACTION_SCANNER_FINISHED;
					EventBus.getDefault().post(message);
				}

				mIsStop = false;
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
	}

	public void cancel() {
		mIsStop = true;
	}

	/**
	 * 
	 * 搜索文件
	 * 
	 * @param rootFile
	 *            根目录
	 * @return void
	 */
	private void searchMdeiaFile(File rootFile) {
		try {

			L.v(TAG, "searchMdeia", "rootFile:" + rootFile);

			if (rootFile == null
					|| (rootFile != null && rootFile.listFiles() == null)) {
				return;
			}
			File[] fileArray = rootFile.listFiles();
			for (File file : fileArray) {
				if (mIsStop) {
					// 停止扫描
					L.e(TAG, "searchMdeia", "searchMdeia stop");
					Message message = new Message();
					message.what = StorageModule.MSG_ACTION_SCANNER_STOPPED;
					EventBus.getDefault().post(message);
					return;
				}

				// 判断文件是否存在
				if (file == null || (file != null && !file.exists())) {
					continue;
				}

				if (file.isDirectory()) {

					searchMdeiaFile(file);

				} else {

					mTotalFileNum++;

					L.v(TAG, "searchMdeia", "file:" + file.getAbsolutePath());

					// 读取文件信息
					MediaFile mediaFile = getMediaFileByFile(file);

					// 判断是否是媒体文件
					if (mediaFile == null) {
						continue;
					}

					mMediaFileNum++;

					int postion = isContainsPath(mMediaFolderList,
							file.getParent());

					if (postion == -1) {

						MediaFolder folder = new MediaFolder();
						folder.setMediaFolderPath(file.getParent());

						File parentFile = file.getParentFile();
						if (parentFile != null) {
							String parentFilePath = parentFile.getParent();
							folder.setMediaFolderParentPath(parentFilePath);
							if (!"".equals(parentFilePath)) {
								folder.setMediaFolderName(parentFile.getPath()
										.substring(
												parentFile.getPath()
														.lastIndexOf("/") + 1));
							}

						}

						mMediaFileList.add(mediaFile);

						folder.addMediaFile(mediaFile);

						mMediaFolderList.add(folder);

					} else {

						MediaFolder folder = (MediaFolder) mMediaFolderList
								.get(postion);

						folder.addMediaFile(mediaFile);

						mMediaFileList.add(mediaFile);

						mMediaFolderList.set(postion, folder);

					}

					// 发送进度
					sendProcessingMessage(mMediaFileNum, mTotalFileNum);
				}
			}
		} catch (Exception e) {
			L.e(TAG, "Exception", e);
			return;
		}
	}

	/**
	 * 根据文件返回媒体文件对象
	 * 
	 * @param file
	 *            文件对象
	 * @return 媒体文件
	 */
	public MediaFile getMediaFileByFile(File file) {

		String fileName = file.getName();
		int dotIndex = fileName.lastIndexOf(".");
		if (dotIndex == -1) {
			return null;
		}
		String extension = fileName.substring(dotIndex + 1).toLowerCase(
				Locale.getDefault());

		// 非自拍视频进行文件大小过滤,自拍视频忽略大小比对
		if (!file.getParent().toLowerCase(Locale.getDefault())
				.contains(StorageConfig.SYSTEM_AUTODYNE_VIDEO_PATH)
				&& !file.getParent().toLowerCase(Locale.getDefault())
						.contains(StorageConfig.FONE_AUTODYNE_VIDEO_PATH)) {

			// 过滤文件大小,1M以下的视频忽略
			if (file.length() < StorageConfig.FILE_SIZE_FILTER_CONDITION) {
				return null;
			}

		}

		// 匹配视频
		if (!StorageConfig.matchVideoFile(extension)) {
			return null;
		}

		MediaFile mediaFile = new MediaFile();
		String path = file.getAbsolutePath();
		mediaFile.setMediaFileNameSuffix(fileName);
		mediaFile.setMediaFileParentPath(file.getParent());
		mediaFile.setMediaFileName(fileName.substring(0, dotIndex));
		mediaFile.setMediaFilePath(path);
		mediaFile.setMediaFileDateModified(file.lastModified());
		mediaFile.setMediaFileSize(file.length());
		return mediaFile;
	}

	/**
	 * 
	 * 判断路径是否在当前集合中重复
	 * 
	 * @param mediaFolderList
	 *            路径集合
	 * @param parentPath
	 *            比对的路径
	 * @return int 重复路径的索引,否则返回-1
	 */
	public int isContainsPath(ArrayList<MediaFolder> mediaFolderList,
			String path) {

		if (mediaFolderList == null) {
			L.e(TAG, "isPathInArray", "mediaFolderList is null");
			return -1;
		}

		if (mediaFolderList.size() == 0) {
			L.e(TAG, "isPathInArray", "mediaFolderList.size() == 1");
			return -1;
		}
		int index = 0;
		for (MediaFolder mediaFolder : mediaFolderList) {
			if (mediaFolder.getMediaFolderPath().equals(path)) {
				return index;
			}
			index++;
		}

		return -1;
	}

	/**
	 * 
	 * 发送进度信息
	 * 
	 * @param mediaFileNum
	 *            符合要求的文件数
	 * @param totalFileNum
	 *            已搜索到的文件数
	 * @return void
	 */
	private void sendProcessingMessage(long mediaFileNum, long totalFileNum) {
		Message message = new Message();
		message.what = StorageModule.MSG_ACTION_SCANNER_PROCESSING;
		StringBuffer stringBuffer = new StringBuffer(mContext.getResources()
				.getString(R.string.search_mdeia_msg))
				.append(mediaFileNum)
				.append(File.separator)
				.append(totalFileNum)
				.append(mContext.getResources().getString(
						R.string.search_cancel_msg));
		L.v(TAG, stringBuffer.toString());
		message.obj = stringBuffer.toString();
		EventBus.getDefault().post(message);
	}
}
